package com.liry.security.controller;

import com.liry.security.domain.entity.SysUser;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.security.RolesAllowed;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author ALI
 * @since 2023/6/13
 */
@RestController
public class MethodCongroller {

    // 这种方式匹配的是ROLE_dev，内部会默认添加ROLE_
    @PreAuthorize("hasRole('dev')")
    @GetMapping("/method1")
    public String method1() {
        return "method1";
    }

    // 匹配ROLE_dev
    @PreAuthorize("hasAuthority('ROLE_dev')")
    @GetMapping("/method2")
    public String method2() {
        return "method2";
    }

    // 只能查询 id < 10 的数据
    @PreAuthorize("#id < 10")
    @GetMapping("/method3")
    public String method3(Integer id) {
        return "method3-" + id;
    }

    // 只能由用户名带后缀 _ad 的访问
    @PreAuthorize("principal.username.endsWith('_ad')")
    @GetMapping("/method4")
    public String method4() {
        return "method4";
    }

    // 只能由用户名和参数相等
    @PreAuthorize("principal.username.equals(#name)")
    @GetMapping("/method44")
    public String method44(String name) {
        return "method44";
    }

    // 新增的用户，用户名只能是 _ad 结尾
    @PreAuthorize("#user.username.endsWith('_ad')")
    @PostMapping("/method5")
    public String method5(@RequestBody SysUser user) {
        return "method5";
    }

    // 配置了 ROLE_admin > ROLE_dev
    // dev 继承了admin 的权限，使用admin的用户访问
    @PreAuthorize("hasRole('dev')")
    @GetMapping("/method6")
    public String method6() {
        return "method6";
    }

    // 是否是 admin 的角色，无关大小写
    // principal 为内置对象
    @PreAuthorize("principal?.isAdmin()")
    @GetMapping("/method7")
    public String method7() {
        return "method7";
    }

    // 返回的用户id必须 =10
    // principal 为内置对象
    @PostAuthorize("returnObject.id.equals('10')")
    @GetMapping("/method8")
    public SysUser method8() {
        SysUser result = new SysUser();
        result.setId("10");
        return result;
    }

    // 过滤出 id= 1 的元素
    // filterObject 内置对象，表示集合中的每一个元素
    // userList 集合对象
    @PreFilter(value = "filterObject.id.equals('1')", filterTarget = "userList")
    @PostMapping("/method9")
    public List<SysUser> method9(@RequestBody List<SysUser> userList) {
        return userList;
    }

    // 过滤出 id != 1 的元素
    @PostFilter(value = "!filterObject.id.equals('1')")
    @PostMapping("/method10")
    public List<SysUser> method10(@RequestBody List<SysUser> userList) {
        return userList;
    }

    // 只允许角色为 ROLE_admin 的用户访问
    @Secured("ROLE_admin")
    @PostMapping("/method11")
    public List<SysUser> method11(@RequestBody List<SysUser> userList) {
        return userList;
    }

    // 允许角色为 ROLE_admin ROLE_dev 的用户访问
    @RolesAllowed({"ROLE_admin", "ROLE_dev"})
    @PostMapping("/method12")
    public List<SysUser> method12(@RequestBody List<SysUser> userList) {
        return userList;
    }
}
